import colCache from '../../../utils/col-cache';
import XmlStream from '../../../utils/xml-stream';

import BaseXform from '../base-xform';
import TwoCellAnchorXform from './two-cell-anchor-xform';
import OneCellAnchorXform from './one-cell-anchor-xform';

function getAnchorType(model) {
    const range = typeof model.range === 'string' ? colCache.decode(model.range) : model.range;

    return range.br ? 'xdr:twoCellAnchor' : 'xdr:oneCellAnchor';
}

class DrawingXform extends BaseXform {
    constructor() {
        super();

        this.map = {
            'xdr:twoCellAnchor': new TwoCellAnchorXform(),
            'xdr:oneCellAnchor': new OneCellAnchorXform(),
        };
    }

    prepare(model) {
        model.anchors.forEach((item, index) => {
            item.anchorType = getAnchorType(item);
            const anchor = this.map[item.anchorType];
            anchor.prepare(item, { index });
        });
    }

    get tag() {
        return 'xdr:wsDr';
    }

    render(xmlStream, model) {
        xmlStream.openXml(XmlStream.StdDocAttributes);
        xmlStream.openNode(this.tag, DrawingXform.DRAWING_ATTRIBUTES);

        model.anchors.forEach(item => {
            const anchor = this.map[item.anchorType];
            anchor.render(xmlStream, item);
        });

        xmlStream.closeNode();
    }

    parseXmlObject(node) {

        let hasvalue = false
        node._elements?.forEach(item => {
            if (item._name === this.tag) {
                this.reset();
                this.model = {
                    anchors: [],
                };
                item._elements?.forEach(ele => {
                    this.parser = this.map[ele._name];
                    if (this.parser) {
                        this.parser.parseXmlObject(ele);
                        this.model.anchors.push(this.parser.model);
                        this.parser = undefined;
                    }
                })
                hasvalue = true;
            }
        })

        return hasvalue;
    }

    parseOpen(node) {
        if (this.parser) {
            this.parser.parseOpen(node);
            return true;
        }
        switch (node.name) {
            case this.tag:
                this.reset();
                this.model = {
                    anchors: [],
                };
                break;
            default:
                this.parser = this.map[node.name];
                if (this.parser) {
                    this.parser.parseOpen(node);
                }
                break;
        }
        return true;
    }

    parseText(text) {
        if (this.parser) {
            this.parser.parseText(text);
        }
    }

    parseClose(name) {
        if (this.parser) {
            if (!this.parser.parseClose(name)) {
                this.model.anchors.push(this.parser.model);
                this.parser = undefined;
            }
            return true;
        }
        switch (name) {
            case this.tag:
                return false;
            default:
            // could be some unrecognised tags
                return true;
        }
    }

    reconcile(model, options) {
        model?.anchors.forEach(anchor => {
            if (anchor.br) {
                this.map['xdr:twoCellAnchor'].reconcile(anchor, options);
            } else {
                this.map['xdr:oneCellAnchor'].reconcile(anchor, options);
            }
        });
    }
}

DrawingXform.DRAWING_ATTRIBUTES = {
    'xmlns:xdr': 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing',
    'xmlns:a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
};

export default DrawingXform;
